home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.004 / xemacs-1 / xemacs-19.13 / lisp / oobr / tree-x / intf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-14  |  53.2 KB  |  1,985 lines

  1. /* ----------------------------------------------------------------------------
  2.  * File    : intf.c
  3.  * Purpose : X11/Athena interface code
  4.  * ----------------------------------------------------------------------------
  5.  */
  6.  
  7. #define GLOBALS 1
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <fcntl.h>
  12.  
  13. #include "X11/IntrinsicP.h"
  14. #include <X11/ShellP.h>
  15.  
  16. #include <X11/Intrinsic.h>
  17. #include <X11/StringDefs.h>
  18. #include <X11/Xaw/Box.h>
  19. #include <X11/Xaw/Simple.h>
  20. #include <X11/Xaw/MenuButton.h>
  21. #include <X11/Xaw/SimpleMenu.h>
  22. #include <X11/Xaw/SmeBSB.h>
  23. #include <X11/Xaw/SmeLine.h>
  24. #include <X11/Xaw/Form.h>
  25. #include <X11/Xaw/Label.h>
  26. #include <X11/Xaw/Dialog.h>
  27. #include <X11/Xaw/AsciiText.h>
  28. #include <X11/Xaw/AsciiSrc.h>
  29. #include <X11/Xaw/Viewport.h>
  30. #include <X11/Xaw/Scrollbar.h>
  31. #include <X11/Xaw/Paned.h>
  32. #include <X11/Xaw/Panner.h>
  33. #include <X11/Xaw/Reports.h>
  34.  
  35. #include "defs.h"
  36. #include "tree.h"
  37. #include "dbl.h"
  38. #include "intf.h"
  39. #include "rsrc.h"
  40. #include "input.h"
  41. #include "help.h"
  42.  
  43. #include <X11/cursorfont.h>
  44.  
  45.  
  46. /* ------------------------------------------------------------------------- */
  47. /*                Global Variables                             */
  48. /* ------------------------------------------------------------------------- */
  49.  
  50. extern char  *EnvNm;    /* Stores name of current Envir file */
  51.  
  52. Atom          wm_delete_window;
  53. Widget        TreeTopLevel;
  54. Widget        TreeDrawingArea;
  55. Display      *TreeDisplay;
  56. XtAppContext  app;
  57. int           TreeScreen;
  58. int           TreeContourWidth;
  59. int           TreeBorderSize = BORDER_SIZE;
  60. int           TreeParentDistance = PARENT_DISTANCE;
  61. XFontStruct  *TreeLabelFont;
  62. DoubleBuffer *TreeDrawingAreaDB;
  63. ContourOption TreeShowContourOption = NoContours;
  64. DensityOption TreeLayoutDensity = Fixed;
  65. char          TreeShowSteps =  FALSE;
  66. char          TreeAlignNodes = FALSE;
  67. char          PauseAfterStep    = FALSE;
  68.  
  69. /* ------------------------------------------------------------------------- */
  70. /*                Local Variables                              */
  71. /* ------------------------------------------------------------------------- */
  72.  
  73. static Tree *PopupNode;        /* node selected for popup */
  74. static NodePosition NodePos;
  75.  
  76. static Widget mainWindow;
  77. static Widget topForm;
  78.  
  79. static Widget statusLabel;
  80. static Widget statusText;
  81.  
  82. static Widget scrolledWindow;
  83.  
  84. static Widget helpShell;
  85. static Widget helpForm;
  86. static Widget helpScrollWindow;
  87. static Widget helpText;
  88. static Widget helpDoneButton;
  89. static Widget helpTitle;
  90. static Widget helpFrame;
  91.  
  92. static Widget treeMenubar;
  93. static Widget treeMenus[NUM_MENUS];
  94. static Widget treeMenuBtns[NUM_MENUS - 1];   /* don't need button for */
  95.                          /* node popup menu       */
  96.  
  97. static Widget treeMenuItems[TREE_MENU_ITEMS];
  98. static Widget layoutMenuItems[LAYOUT_MENU_ITEMS];
  99. static Widget nodeMenuItems[NODE_MENU_ITEMS];
  100. static Widget helpBtn;
  101.  
  102. static String labelStr[NUM_MENU_STRS];
  103. static String errStr[NUM_ERRS];
  104.  
  105. static Widget dialog[NUM_DLG];
  106.  
  107. /* globals used for state values */
  108.  
  109. static Widget dlgLevelScale, dlgLevelValuator, 
  110.               dlgSiblingValuator, dlgSiblingScale;
  111. static int dlgLevelValue;
  112. static int dlgSiblingValue;
  113. static int loading_file = 0;
  114.  
  115. static Pixmap check_pixmap, slider_pixmap;
  116.  
  117. static Boolean nodeFound;
  118.  
  119. static int    PauseTime         = ANIMATION_SPEED_FAST;
  120. static Cursor PauseCursor;
  121.  
  122. static XtResource applRsrcsDesc[] = {
  123.    {
  124.       TrNbackgroundColor,       TrCBackgroundColor,
  125.       XtRPixel,                 sizeof(Pixel),
  126.       XtOffset(ApplRsrcDataPtr, background_color),
  127.       XtRString,                TrDefaultBackgroundColor
  128.    },
  129.    {
  130.       TrNtreeColor,             TrCTreeColor,
  131.       XtRPixel,                 sizeof(Pixel),
  132.       XtOffset(ApplRsrcDataPtr, tree_color),
  133.       XtRString,                TrDefaultTreeColor
  134.    },
  135.    {
  136.       TrNcontourColor,          TrCContourColor,
  137.       XtRPixel,                 sizeof(Pixel),
  138.       XtOffset(ApplRsrcDataPtr, contour_color),
  139.       XtRString,                TrDefaultContourColor
  140.    },
  141.    {
  142.       TrNsplitColor,            TrCSplitColor,
  143.       XtRPixel,                 sizeof(Pixel),
  144.       XtOffset(ApplRsrcDataPtr, split_color),
  145.       XtRString,                TrDefaultSplitColor
  146.    },
  147.    {
  148.       TrNhighlightColor,        TrCHighlightColor,
  149.       XtRPixel,                 sizeof(Pixel),
  150.       XtOffset(ApplRsrcDataPtr, highlight_color),
  151.       XtRString,                TrDefaultHighlightColor
  152.    },
  153.    {
  154.       TrNactionColor,           TrCActionColor,
  155.       XtRPixel,                 sizeof(Pixel),
  156.       XtOffset(ApplRsrcDataPtr, action_color),
  157.       XtRString,                TrDefaultActionColor
  158.    },
  159.    {
  160.       TrNcontourWidth,          TrCContourWidth,
  161.       XtRInt,                   sizeof(int),
  162.       XtOffset(ApplRsrcDataPtr, contour_width),
  163.       XtRImmediate,             (XtPointer) TrDefaultContourWidth
  164.    },
  165. };
  166.  
  167. static void popdown_action();
  168. static void activate_action();
  169. static void quit_action();
  170. static void Action();
  171.  
  172. static void select_action();
  173. static void button_action();
  174. static void menu_popup_action();
  175.  
  176. static void set_levelscale_CB();
  177. static void levelscale_CB();
  178. static void set_siblingscale_CB();
  179. static void siblingscale_CB();
  180. static void set_levelvalue_CB();
  181. static void set_siblingvalue_CB();
  182. static void levelvalue_CB();
  183. static void siblingvalue_CB();
  184.  
  185. static void center_widget();
  186.  
  187. static XtActionsRec local_actions[] = {
  188.   {"wmpopdown", popdown_action},
  189.   {"dlg_activate", activate_action},
  190.   {"node_select", select_action},
  191.   {"node_menu_prepare", button_action},
  192.   {"maybe_menu_popup", menu_popup_action},
  193.   {"quit", quit_action},
  194. };
  195.  
  196. String fallback_resources[]  = {
  197. "*statusText.width:                      310",
  198. "*treeDrawingArea.width:                 310",
  199. "*treeDrawingArea.height:                400",
  200. "*Text.Font:          -*-lucidatypewriter-medium-r-*-*-12-*-*-*-*-*-iso8859-1",
  201. "*Label.Font:          -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1",
  202. "*Command.Font:          -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
  203. "*SimpleMenu.Font:    -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
  204. "*SmeBSB.Font:          -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
  205. "*MenuButton.Font:    -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
  206. "*List.Font:          -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
  207. "*treeMenuBtn.label:            Tree",
  208. "*layoutMenuBtn.label:            Layout",
  209. "*helpBtn.label:            Help...",
  210. "*treeMenu*treeMenuNew.label:        New Tree",
  211. "*treeMenu*treeMenuLoad.label:        Load Tree",
  212. "*treeMenu*treeMenuSave.label:        Save Tree",
  213. "*treeMenu*treeMenuQuit.label:        Quit",
  214. "*layoutMenu*layoutMenuFixed.label:    Fixed",
  215. "*layoutMenu*layoutMenuVariable.label:    Variable",
  216. "*layoutMenu*layoutMenuSpacing.label:    Spacing...",
  217. "*layoutMenu*layoutMenuAlignNodes.label: Align Nodes on Level",
  218. "*dlgNewTree.title:            New Tree",
  219. "*dlgNodeName.title:            Node Name",
  220. "*dlgInfo.title:            Information",
  221. "*dlgError.title:            Error!",
  222. "*dlgSpacing.title:            Tree Node Spacing",
  223. "*helpShell.title:            Help",
  224. "*dlgNewTreeForm.label:            Enter name of root node:",
  225. "*dlgNodeNameForm.label:        Enter name of new node:",
  226. "*dlgFileForm.label:            Enter name of file:",
  227. "*dlgInfoForm.label:            Information:",
  228. "*dlgErrorForm.label:            Error:",
  229. "*dlgSpacing.label:            Spacing Dialog",
  230. "*dlgLevelLabel.label:            Level spacing:",
  231. "*dlgSiblingLabel.label:        Sibling spacing:",
  232. "*dlgLevelValuator.width:        40",
  233. "*dlgLevelValuator.width:        40",
  234. "*dlgNewTreeOk.label:            Ok",
  235. "*dlgNewTreeCancel.label:        Cancel",
  236. "*dlgFileOk.label:            Ok",
  237. "*dlgFileCancel.label:            Cancel",
  238. "*dlgInfoButton.label:            Acknowledged",
  239. "*dlgErrorButton.label:            Acknowledged",
  240. "*dlgOkButton.label:            Ok",
  241. "*dlgCancelButton.label:        Cancel",
  242. "*dlgNodeNameOk.label:            Ok",
  243. "*dlgNodeNameCancel.label:        Cancel",
  244. "*helpDoneButton.label:            Dismiss",
  245. "*helpTitle.label:            Help for Drawing Dynamic Trees",
  246. "*treeDrawingArea.Translations: #override \\n\
  247.                                 <Btn1Down>:    node_select(EDIT)\\n\
  248.                                 <Btn2Down>:    node_select(VIEW)\\n\
  249.                                 <Btn3Down>:    XawPositionSimpleMenu(nodeMenu)node_menu_prepare()XtMenuPopup(nodeMenu)\\n",
  250. NULL,
  251. };
  252.  
  253. static ApplRsrcData    applRsrcs;
  254. static ApplRsrcDataPtr applRsrcsPtr;
  255.  
  256. /* included bitmaps */
  257.  
  258. #define gray_width 8
  259. #define gray_height 8
  260. static unsigned char gray_bits[] = {
  261.   0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa
  262. };
  263.  
  264. /* This is a check mark stolen from the xmh application. :) */
  265. #define check_width 9
  266. #define check_height 8
  267. static unsigned char check_bits[] = {
  268.   0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00,
  269.   0x31, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x04, 0x00
  270. };
  271.  
  272. #define slider_pixmap_width 4
  273. #define slider_pixmap_height 4
  274. static char slider_pixmap_bits[] = {
  275.   0x05, 0x0a, 0x05, 0x0a
  276. };
  277.  
  278. /* ------------------------------------------------------------------------- */
  279. /*             Forward Function Declarations                       */
  280. /* ------------------------------------------------------------------------- */
  281.  
  282. static void popup_dialog();
  283.  
  284. static void Quit_CB();
  285.  
  286. static void Contours_CB();
  287. static void ShowContours_CB();
  288. static void Pause_CB();
  289. static void Speed_CB();
  290.  
  291. static void Help_CB();
  292. static void HelpDone_CB();
  293. static void Scale_CB();
  294.  
  295. static void TreeMenu_CB();
  296. static void LayoutMenu_CB();
  297. static void NodeMenu_CB();
  298.  
  299. static void NodeLabel_CB();
  300. static void NewTree_CB();
  301. static void File_CB();
  302.  
  303. static void Popdown_CB();
  304. static void ButtonHandler();
  305.  
  306. extern void ExposeHandler();
  307.  
  308. /* ------------------------------------------------------------------------- */
  309. /*                   Functions                                 */
  310. /* ------------------------------------------------------------------------- */
  311.  
  312. /* ----------------------------------------------------------------------------
  313.  * 
  314.  *   Status() displays the specified text in the status area.
  315.  *   'urgent' overrides the value of TreeShowSteps.
  316.  * 
  317.  * ----------------------------------------------------------------------------
  318.  */
  319.  
  320. void
  321. StatusMsg(msg, urgent)
  322.      char *msg;
  323.      int  urgent;
  324. {
  325.   if (TreeShowSteps || urgent) 
  326.     XtVaSetValues(statusText, XtNlabel, msg, NULL);
  327. }
  328.  
  329.  
  330. /* ----------------------------------------------------------------------------
  331.  * 
  332.  *  Pause is a trivial function, for the benefit of interface-dependent code
  333.  *  inside tree.c. This avoids having to include X11 stuff inside that file.
  334.  *  PauseTime is expected to contain an integer indicating 1/10ths of a sec.
  335.  * 
  336.  * ----------------------------------------------------------------------------
  337.  */
  338.  
  339. void
  340. Pause()
  341. {
  342.   XEvent event;
  343.   
  344.   if (PauseAfterStep) {
  345.     XGrabKeyboard(TreeDisplay, XtWindow(TreeTopLevel), False,
  346.           GrabModeAsync, GrabModeAsync, CurrentTime);
  347.     XGrabPointer(TreeDisplay, XtWindow(TreeTopLevel), False,
  348.          ButtonPressMask | ButtonReleaseMask,
  349.          GrabModeAsync, GrabModeAsync, None,
  350.          PauseCursor, CurrentTime);
  351.     XMaskEvent(TreeDisplay, ButtonPressMask | KeyPress, &event);
  352.     XUngrabPointer(TreeDisplay, CurrentTime);
  353.     XUngrabKeyboard(TreeDisplay, CurrentTime);
  354.   }
  355.   else if (TreeShowSteps) {
  356.     XSync(TreeDisplay, 0);
  357.     usleep(PauseTime * 100000);
  358.   }
  359. }
  360.  
  361. /* ----------------------------------------------------------------------------
  362.  * 
  363.  *   BuildPopupMenus() builds the popup menus for use in the application
  364.  *   window.
  365.  * 
  366.  * ----------------------------------------------------------------------------
  367.  */
  368.  
  369. void
  370. BuildPopupMenus(parent)
  371.      Widget parent;
  372. {
  373.   Arg      args[2];
  374.   String   xstr;
  375.   
  376.   labelStr[STR_NODE_COLLAPSE] = "Collapse Node";
  377.   labelStr[STR_NODE_EXPAND]   = "Expand Node";
  378.   
  379.   treeMenus[NODE_MENU] = XtVaCreatePopupShell("nodeMenu",
  380.                           simpleMenuWidgetClass,
  381.                           parent, 
  382.                           XtNlabel, " ",
  383.                           NULL);
  384.   
  385.   (void)  XtVaCreateManagedWidget("nodeMenuAddChild", smeLineObjectClass,
  386.                   treeMenus[NODE_MENU],
  387.                   NULL);
  388.   
  389.   nodeMenuItems[NODE_MENU_ADD_CHILD] = 
  390.     XtVaCreateManagedWidget("nodeMenuAddChild", smeBSBObjectClass,
  391.                 treeMenus[NODE_MENU],
  392.                 XtNlabel, "Add Child",
  393.                 NULL);
  394.   XtAddCallback(nodeMenuItems[NODE_MENU_ADD_CHILD],
  395.         XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_ADD_CHILD);
  396.   
  397.   nodeMenuItems[NODE_MENU_ADD_BEFORE] = 
  398.     XtVaCreateManagedWidget("nodeMenuAddSiblingBefore", smeBSBObjectClass,
  399.                 treeMenus[NODE_MENU],
  400.                 XtNlabel, "Add Sibling Before",
  401.                 NULL);
  402.   XtAddCallback(nodeMenuItems[NODE_MENU_ADD_BEFORE],
  403.          XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_ADD_BEFORE);
  404.          
  405.    nodeMenuItems[NODE_MENU_ADD_AFTER] = 
  406.        XtVaCreateManagedWidget("nodeMenuAddSiblingAfter", smeBSBObjectClass,
  407.                    treeMenus[NODE_MENU],
  408.                    XtNlabel, "Add Sibling After",
  409.                    NULL);
  410.    XtAddCallback(nodeMenuItems[NODE_MENU_ADD_AFTER],
  411.          XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_ADD_AFTER);
  412.  
  413.    nodeMenuItems[NODE_MENU_ELISION] =
  414.        XtVaCreateManagedWidget("nodeMenuElision", smeBSBObjectClass,
  415.                    treeMenus[NODE_MENU],
  416.                    XtNlabel, labelStr[STR_NODE_COLLAPSE],
  417.                    NULL);
  418.    XtAddCallback(nodeMenuItems[NODE_MENU_ELISION],
  419.          XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_ELISION);
  420.  
  421.    
  422.    nodeMenuItems[NODE_MENU_DELETE] =
  423.        XtVaCreateManagedWidget("nodeMenuDeleteNode", smeBSBObjectClass,
  424.                    treeMenus[NODE_MENU],
  425.                    XtNlabel, "Delete Node",
  426.                    NULL);
  427.    XtAddCallback(nodeMenuItems[NODE_MENU_DELETE],
  428.          XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_DELETE);
  429.  
  430.          
  431. }
  432.  
  433. /* ----------------------------------------------------------------------------
  434.  * 
  435.  *   BuildMenubar() builds the menubar that appears in the main window.
  436.  * 
  437.  * ----------------------------------------------------------------------------
  438.  */
  439.  
  440.  
  441. void
  442. BuildMenubar(parent)
  443.    Widget parent;
  444. {
  445.    Arg args[4];
  446.    int i;
  447.    Widget box;
  448.  
  449.    box = XtVaCreateManagedWidget("menuBox",
  450.                  boxWidgetClass,
  451.                  parent,
  452.                  XtNshowGrip, FALSE,
  453.                  XtNborderWidth, 0,
  454.                  NULL);
  455.                  
  456.  
  457.    /* menu button widgets */
  458.    treeMenuBtns[TREE_MENU] = 
  459.        XtVaCreateManagedWidget("treeMenuBtn",
  460.                    menuButtonWidgetClass,
  461.                    box,
  462.                    XtNmenuName, "treeMenu",
  463.                    NULL);
  464.    treeMenuBtns[LAYOUT_MENU] =
  465.        XtVaCreateManagedWidget("layoutMenuBtn",
  466.                    menuButtonWidgetClass,
  467.                    box,
  468.                    XtNmenuName, "layoutMenu",
  469.                    NULL);
  470.  
  471.    helpBtn = XtVaCreateManagedWidget("helpBtn",
  472.                      commandWidgetClass,
  473.                      box,
  474.                      NULL);
  475.  
  476.    XtAddCallback(helpBtn, XtNcallback, Help_CB, NULL);
  477.  
  478.    /* create pulldwon menus */
  479.  
  480.    treeMenus[TREE_MENU] = XtVaCreatePopupShell("treeMenu",
  481.                            simpleMenuWidgetClass,
  482.                            treeMenuBtns[TREE_MENU],
  483.                            NULL, 0);
  484.    treeMenus[LAYOUT_MENU] = XtVaCreatePopupShell("layoutMenu",
  485.                          simpleMenuWidgetClass,
  486.                          treeMenuBtns[LAYOUT_MENU],
  487.                          NULL, 0);
  488.  
  489.  
  490.    /* adding menu entries */
  491.    
  492.    /* Tree menu */
  493.  
  494.    treeMenuItems[TREE_MENU_NEW] = 
  495.        XtVaCreateManagedWidget("treeMenuNew", smeBSBObjectClass,
  496.                    treeMenus[TREE_MENU],
  497.                    NULL);
  498.    XtAddCallback(treeMenuItems[TREE_MENU_NEW],
  499.          XtNcallback, TreeMenu_CB, TREE_MENU_NEW);
  500.    
  501.    treeMenuItems[TREE_MENU_LOAD] = 
  502.        XtVaCreateManagedWidget("treeMenuLoad", smeBSBObjectClass,
  503.                    treeMenus[TREE_MENU],
  504.                    NULL);
  505.    XtAddCallback(treeMenuItems[TREE_MENU_LOAD],
  506.          XtNcallback, TreeMenu_CB, (XtPointer) TREE_MENU_LOAD);
  507.          
  508.    treeMenuItems[TREE_MENU_SAVE] = 
  509.        XtVaCreateManagedWidget("treeMenuSave", smeBSBObjectClass,
  510.                    treeMenus[TREE_MENU],
  511.                    NULL);
  512.    XtAddCallback(treeMenuItems[TREE_MENU_SAVE],
  513.          XtNcallback, TreeMenu_CB, (XtPointer) TREE_MENU_SAVE);
  514.          
  515.    treeMenuItems[TREE_MENU_SEP1] = 
  516.        XtVaCreateManagedWidget("treeMenuSep1", smeLineObjectClass,
  517.                    treeMenus[TREE_MENU],
  518.                    NULL);
  519.  
  520. #ifdef COMMENT
  521.    treeMenuItems[TREE_MENU_STATS] = 
  522.        XtVaCreateManagedWidget("treeMenuStats", smeBSBObjectClass,
  523.                    treeMenus[TREE_MENU],
  524.                    XtNlabel, labelStr[STR_SHOW_STATS],
  525.                    NULL);
  526.  
  527.    XtAddCallback(treeMenuItems[TREE_MENU_STATS],
  528.          XtNcallback, TreeMenu_CB, (XtPointer) TREE_MENU_STATS);
  529.  
  530.    XtSetSensitive(treeMenuItems[TREE_MENU_STATS], FALSE);
  531.  
  532.    treeMenuItems[TREE_MENU_SEP2] = 
  533.        XtVaCreateManagedWidget("treeMenuSep2", smeLineObjectClass,
  534.                    treeMenus[TREE_MENU],
  535.                    NULL);
  536. #endif /* COMMENT */
  537.    
  538.    treeMenuItems[TREE_MENU_QUIT] = 
  539.        XtVaCreateManagedWidget("treeMenuQuit", smeBSBObjectClass,
  540.                    treeMenus[TREE_MENU],
  541.                    NULL);
  542.    XtAddCallback(treeMenuItems[TREE_MENU_QUIT],
  543.          XtNcallback, TreeMenu_CB, (XtPointer) TREE_MENU_QUIT);
  544.          
  545.  
  546.  
  547.    /* Layout menu */
  548.  
  549. #ifdef COMMENT
  550.    treeMenuItems[LAYOUT_MENU_FIXED] = 
  551.        XtVaCreateManagedWidget("layoutMenuFixed", smeBSBObjectClass,
  552.                    treeMenus[LAYOUT_MENU],
  553.                    XtNleftMargin, 18,
  554.                    NULL);
  555.  
  556.    XtAddCallback(treeMenuItems[LAYOUT_MENU_FIXED],
  557.          XtNcallback, LayoutMenu_CB, (XtPointer) LAYOUT_MENU_FIXED);
  558.  
  559.    treeMenuItems[LAYOUT_MENU_VARIABLE] = 
  560.        XtVaCreateManagedWidget("layoutMenuVariable", smeBSBObjectClass,
  561.                    treeMenus[LAYOUT_MENU],
  562.                    XtNleftMargin, 18,
  563.                    NULL);
  564.  
  565.    XtAddCallback(treeMenuItems[LAYOUT_MENU_VARIABLE],
  566.          XtNcallback, LayoutMenu_CB, (XtPointer) LAYOUT_MENU_VARIABLE);
  567.  
  568.  
  569.    treeMenuItems[LAYOUT_MENU_SEP1] = 
  570.        XtVaCreateManagedWidget("layoutSep1", smeLineObjectClass,
  571.                    treeMenus[LAYOUT_MENU],
  572.                    NULL);
  573. #endif /* COMMENT */
  574.  
  575.    treeMenuItems[LAYOUT_MENU_SPACING] = 
  576.        XtVaCreateManagedWidget("layoutMenuSpacing", smeBSBObjectClass,
  577.                    treeMenus[LAYOUT_MENU],
  578.                    XtNleftMargin, 18,
  579.                    NULL);
  580.    XtAddCallback(treeMenuItems[LAYOUT_MENU_SPACING],
  581.          XtNcallback, LayoutMenu_CB, (XtPointer) LAYOUT_MENU_SPACING);
  582.  
  583.    treeMenuItems[LAYOUT_MENU_SEP2] = 
  584.        XtVaCreateManagedWidget("layoutMenuSep2", smeLineObjectClass,
  585.                    treeMenus[LAYOUT_MENU],
  586.                    NULL);
  587.  
  588.    /* the following is a toggle button - we hack it using a bitmap */
  589.    treeMenuItems[LAYOUT_MENU_ALIGN_NODES] = 
  590.        XtVaCreateManagedWidget("layoutMenuAlignNodes", smeBSBObjectClass,
  591.                    treeMenus[LAYOUT_MENU],
  592.                    XtNleftMargin, 18,
  593.                    NULL);
  594.    XtAddCallback(treeMenuItems[LAYOUT_MENU_ALIGN_NODES],
  595.          XtNcallback, LayoutMenu_CB, 
  596.          (XtPointer) LAYOUT_MENU_ALIGN_NODES);
  597.  
  598. }
  599.  
  600. /* ----------------------------------------------------------------------------
  601.  * 
  602.  *   BuildDialogs() builds all the dialogs used in this application. 
  603.  * 
  604.  * ----------------------------------------------------------------------------
  605.  */
  606.  
  607.  
  608. BuildDialogs(parent)
  609.      Widget parent;
  610. {
  611.   int    i;
  612.   Widget 
  613.     tmpwidget, dlgForm, dlgValue, 
  614.     dlgLevelLabel, dlgSiblingLabel, 
  615.     dlgOkButton, dlgCancelButton;
  616.   
  617.   labelStr[STR_LOAD_FILE] = "Name of file to load:";
  618.   labelStr[STR_SAVE_FILE] = "Name of file to save:";
  619.   
  620.   errStr[ERR_OPENFAIL]  = "Failed to open file.";
  621.   errStr[ERR_EMPTYFILE] = "Input file is empty.";
  622.   errStr[ERR_MEMALLOC]  = "Memory allocation failed.";
  623.   errStr[ERR_NOBEGIN] = "End of list does not have a matching beginning.";
  624.   errStr[ERR_NOEND] = "Beginning of list does not have a matching end.";
  625.   errStr[ERR_NOROOT] = "Input file does not have a root label.";
  626.   errStr[ERR_MANYROOT] = "Input file has more than one root label.";
  627.   
  628.   
  629.   dialog[DLG_NEW] = XtVaCreatePopupShell("dlgNewTree",
  630.                      transientShellWidgetClass,
  631.                      parent,
  632.                      XtNresizable, TRUE,
  633.                      NULL);
  634.   
  635.   tmpwidget = XtVaCreateManagedWidget("dlgNewTreeForm",
  636.                       dialogWidgetClass,
  637.                       dialog[DLG_NEW], 
  638.                       XtNresizable, TRUE,
  639.                       XtNvalue, "",
  640.                       NULL);
  641.   
  642.   XawDialogAddButton(tmpwidget, "dlgNewTreeOk", NewTree_CB, 
  643.              (XtPointer) TRUE);
  644.   XawDialogAddButton(tmpwidget, "dlgNewTreeCancel", NewTree_CB, 
  645.              (XtPointer) FALSE);
  646.   
  647.   dlgValue = XtNameToWidget(tmpwidget, "value");
  648.   
  649.   XtOverrideTranslations
  650.     (dlgValue, XtParseTranslationTable
  651.      ("<Key>Return:dlg_activate(dlgNewTreeOk)\n"));
  652.   
  653.   
  654.   dialog[DLG_NODE_NAME] = XtVaCreatePopupShell("dlgNodeName",
  655.                            transientShellWidgetClass,
  656.                            TreeTopLevel,
  657.                            XtNresizable, TRUE,
  658.                            NULL);
  659.                     
  660.   
  661.   tmpwidget= XtVaCreateManagedWidget("dlgNodeNameForm",
  662.                      dialogWidgetClass,
  663.                      dialog[DLG_NODE_NAME], 
  664.                      XtNresizable, TRUE,
  665.                      XtNvalue, "",
  666.                      NULL);
  667.   
  668.   XawDialogAddButton(tmpwidget, "dlgNodeNameOk", NodeLabel_CB, 
  669.              (XtPointer) TRUE);
  670.   XawDialogAddButton(tmpwidget, "dlgNodeNameCancel", NodeLabel_CB, 
  671.              (XtPointer) FALSE);
  672.   
  673.   dlgValue = XtNameToWidget(tmpwidget, "value");
  674.   
  675.   XtOverrideTranslations
  676.     (dlgValue, XtParseTranslationTable
  677.      ("<Key>Return: dlg_activate(dlgNodeNameOk)\n"));
  678.   
  679.  
  680.   dialog[DLG_FILE] = XtVaCreatePopupShell("dlgFile",
  681.                       transientShellWidgetClass,
  682.                       TreeTopLevel, 
  683.                       XtNresizable, TRUE,
  684.                       NULL);
  685.  
  686.   tmpwidget = XtVaCreateManagedWidget("dlgFileForm",
  687.                       dialogWidgetClass,
  688.                       dialog[DLG_FILE], 
  689.                       XtNresizable, TRUE,
  690.                       XtNvalue, "",
  691.                       NULL);
  692.    
  693.   XawDialogAddButton(tmpwidget, "dlgFileOk", File_CB, (XtPointer) TRUE);
  694.   XawDialogAddButton(tmpwidget, "dlgFileCancel", File_CB, (XtPointer) FALSE);
  695.  
  696.   dlgValue = XtNameToWidget(tmpwidget, "value");
  697.   
  698.   XtOverrideTranslations
  699.     (dlgValue, XtParseTranslationTable
  700.      ("<Key>Return:dlg_activate(dlgFileOk)\n"));
  701.   
  702.  
  703.   dialog[DLG_INFO] = XtVaCreatePopupShell("dlgInfo",
  704.                       transientShellWidgetClass,
  705.                       TreeTopLevel, 
  706.                       XtNresizable, TRUE,
  707.                       NULL);
  708.   
  709.   tmpwidget = XtVaCreatePopupShell("dlgInfoForm",
  710.                    dialogWidgetClass,
  711.                    dialog[DLG_INFO], 
  712.                    XtNresizable, TRUE,
  713.                    XtNvalue, "",
  714.                    NULL);
  715.   
  716.   XawDialogAddButton(tmpwidget, "dlgInfoButton", Popdown_CB, 
  717.              (XtPointer) dialog[DLG_INFO]);
  718.   
  719.   
  720.   dialog[DLG_ERROR] = XtVaCreatePopupShell("dlgError",
  721.                        transientShellWidgetClass,
  722.                        TreeTopLevel, 
  723.                        XtNresizable, TRUE,
  724.                        NULL);
  725.    
  726.   tmpwidget = XtVaCreateManagedWidget("dlgErrorForm",
  727.                       dialogWidgetClass,
  728.                       dialog[DLG_ERROR], 
  729.                       XtNresizable, TRUE,
  730.                       XtNvalue, "",
  731.                       NULL);
  732.    
  733.   XawDialogAddButton(tmpwidget, "dlgErrorButton", Popdown_CB, 
  734.              (XtPointer) dialog[DLG_ERROR]);
  735.    
  736.  
  737.   dialog[DLG_SPACING] = XtVaCreatePopupShell("dlgSpacing",
  738.                          transientShellWidgetClass,
  739.                          TreeTopLevel, 
  740.                          XtNresizable, FALSE,
  741.                          NULL);
  742.   dlgForm = XtVaCreateManagedWidget("dlgSpacingForm",
  743.                     formWidgetClass,
  744.                     dialog[DLG_SPACING],
  745.                     XtNresizable, FALSE,
  746.                     NULL);
  747.    
  748.   dlgLevelLabel = XtVaCreateManagedWidget("dlgLevelLabel",
  749.                       labelWidgetClass,
  750.                       dlgForm,
  751.                       XtNfromVert, NULL,
  752.                       XtNfromHoriz, NULL,
  753.                       XtNtop, XawChainTop,
  754.                       XtNbottom, XawChainTop,
  755.                       XtNleft, XawChainLeft,
  756.                       XtNright, XawChainLeft,
  757.                       XtNborderWidth, 0,
  758.                       NULL);
  759.  
  760.   dlgLevelValuator = XtVaCreateManagedWidget("dlgLevelValuator",
  761.                          labelWidgetClass,
  762.                          dlgForm,
  763.                          XtNfromVert, NULL,
  764.                          XtNfromHoriz, dlgLevelLabel,
  765.                          XtNtop, XawChainTop,
  766.                          XtNbottom, XawChainTop,
  767.                          XtNleft, XawChainLeft,
  768.                          XtNright, XawChainLeft,
  769.                          XtNlabel, "   ",
  770.                          NULL);
  771.  
  772.   
  773.   dlgLevelScale = XtVaCreateManagedWidget("dlgLevelScale",
  774.                       pannerWidgetClass,
  775.                       dlgForm,
  776.                       XtNfromVert, dlgLevelLabel,
  777.                       XtNfromHoriz, NULL,
  778.                       XtNtop, XawChainTop,
  779.                       XtNbottom, XawChainTop,
  780.                       XtNleft, XawChainLeft,
  781.                       XtNright, XawChainLeft,
  782.                       XtNcanvasWidth, 110,
  783.                       XtNdefaultScale, 1,
  784.                       XtNinternalSpace, 1,
  785.                       XtNrubberBand, FALSE,
  786.                       XtNshadowThickness, 0,
  787.                       XtNallowOff, FALSE,
  788.                       XtNwidth, 200,
  789.                       XtNsliderWidth, 10,
  790.                       XtNheight, 15,
  791.                       NULL);
  792.   
  793.   XtOverrideTranslations(dlgLevelScale, XtParseTranslationTable("\
  794. <Btn2Down>:        start()\n\
  795. <Btn2Motion>:        move()\n\
  796. <Btn2Up>:        notify()stop()\n\
  797. <Btn3Down>:        abort()\n"));
  798.  
  799.   XtAddCallback(dlgLevelScale, XtNreportCallback, levelscale_CB,
  800.         (XtPointer) dlgLevelValuator);
  801.   XtAddCallback(dlgLevelScale, XtNreportCallback, levelvalue_CB,
  802.         (XtPointer) &dlgLevelValue);
  803.  
  804.   dlgSiblingLabel = XtVaCreateManagedWidget("dlgSiblingLabel",
  805.                         labelWidgetClass,
  806.                         dlgForm,
  807.                         XtNfromVert, dlgLevelScale,
  808.                         XtNfromHoriz, NULL,
  809.                         XtNtop, XawChainTop,
  810.                         XtNbottom, XawChainTop,
  811.                         XtNleft, XawChainLeft,
  812.                         XtNright, XawChainLeft,
  813.                         XtNborderWidth, 0,
  814.                         NULL);
  815.  
  816.   dlgSiblingValuator = XtVaCreateManagedWidget("dlgLevelValuator",
  817.                            labelWidgetClass,
  818.                            dlgForm,
  819.                            XtNfromVert, dlgLevelScale,
  820.                            XtNfromHoriz, dlgSiblingLabel,
  821.                            XtNtop, XawChainTop,
  822.                            XtNbottom, XawChainTop,
  823.                            XtNleft, XawChainLeft,
  824.                            XtNright, XawChainLeft,
  825.                            XtNlabel, "   ",
  826.                            NULL);
  827.   dlgSiblingScale = XtVaCreateManagedWidget("dlgSiblingScale",
  828.                         pannerWidgetClass,
  829.                         dlgForm,
  830.                         XtNfromVert, dlgSiblingLabel,
  831.                         XtNfromHoriz, NULL,
  832.                         XtNtop, XawChainTop,
  833.                         XtNbottom, XawChainTop,
  834.                         XtNleft, XawChainLeft,
  835.                         XtNright, XawChainLeft,
  836.                         XtNcanvasWidth, 110,
  837.                         XtNdefaultScale, 1,
  838.                         XtNinternalSpace, 1,
  839.                         XtNrubberBand, FALSE,
  840.                         XtNshadowThickness, 0,
  841.                         XtNallowOff, FALSE,
  842.                         XtNwidth, 200,
  843.                         XtNsliderWidth, 10,
  844.                         XtNheight, 15,
  845.                         NULL);
  846.   
  847.   XtOverrideTranslations(dlgSiblingScale, XtParseTranslationTable("\
  848. <Btn2Down>:        start()\n\
  849. <Btn2Motion>:        move()\n\
  850. <Btn2Up>:        notify()stop()\n\
  851. <Btn3Down>:        abort()\n"));
  852.  
  853.   XtAddCallback(dlgSiblingScale, XtNreportCallback, siblingscale_CB,
  854.         (XtPointer) dlgSiblingValuator);
  855.   XtAddCallback(dlgSiblingScale, XtNreportCallback, siblingvalue_CB,
  856.         (XtPointer) &dlgSiblingValue);
  857.   
  858.   dlgOkButton = XtVaCreateManagedWidget("dlgOkButton",
  859.                     commandWidgetClass,
  860.                     dlgForm,
  861.                     XtNfromVert, dlgSiblingScale,
  862.                     XtNfromHoriz, NULL,
  863.                     XtNtop, XawChainTop,
  864.                     XtNbottom, XawChainTop,
  865.                     XtNleft, XawChainLeft,
  866.                     XtNright, XawChainLeft,
  867.                     NULL);
  868.   
  869.   dlgCancelButton = XtVaCreateManagedWidget("dlgCancelButton",
  870.                         commandWidgetClass,
  871.                         dlgForm,
  872.                         XtNfromVert, dlgSiblingScale,
  873.                         XtNfromHoriz, dlgOkButton,
  874.                         XtNtop, XawChainTop,
  875.                         XtNbottom, XawChainTop,
  876.                         XtNleft, XawChainLeft,
  877.                         XtNright, XawChainLeft,
  878.                         NULL);
  879.   
  880.   XtAddCallback(dlgOkButton, XtNcallback, Scale_CB, (XtPointer) TRUE);
  881.   XtAddCallback(dlgCancelButton, XtNcallback, Scale_CB, (XtPointer) FALSE);
  882. }
  883.  
  884. /* ----------------------------------------------------------------------------
  885.  * 
  886.  *   BuildHelpWindow() builds the help window that is displayed when the
  887.  *   Help button on the application main window is pressed.
  888.  * 
  889.  * ----------------------------------------------------------------------------
  890.  */
  891.  
  892.  
  893. static void
  894. BuildHelpWindow(parent)
  895.      Widget parent;
  896. {
  897.   int    i;
  898.  
  899.   helpShell = XtVaCreatePopupShell("helpShell", transientShellWidgetClass,
  900.                    parent,
  901.                    NULL);
  902.   
  903.   helpForm = XtVaCreateManagedWidget("helpForm",
  904.                      formWidgetClass,
  905.                      helpShell,
  906.                      NULL);
  907.  
  908.   helpDoneButton = XtVaCreateManagedWidget("helpDoneButton",
  909.                        commandWidgetClass,
  910.                        helpForm,
  911.                        XtNfromVert, NULL,
  912.                        XtNfromHoriz, NULL,
  913.                        XtNtop, XawChainTop,
  914.                        XtNbottom, XawChainTop,
  915.                        XtNleft, XawChainLeft,
  916.                        XtNright, XawChainLeft,
  917.                        NULL);
  918.   
  919.   XtAddCallback(helpDoneButton, XtNcallback, Popdown_CB, 
  920.         (XtPointer) helpShell);
  921.  
  922.   helpTitle = XtVaCreateManagedWidget("helpTitle",
  923.                       labelWidgetClass,
  924.                       helpForm,
  925.                       XtNfromVert, NULL,
  926.                       XtNfromHoriz, helpDoneButton,
  927.                       XtNtop, XawChainTop,
  928.                       XtNbottom, XawChainTop,
  929.                       XtNleft, XawChainLeft,
  930.                       XtNright, XawChainLeft,
  931.                       XtNborderWidth, 0,
  932.                       XtNlabel, "",
  933.                       NULL);
  934.  
  935.   helpText = XtVaCreateManagedWidget("helpText",
  936.                      asciiTextWidgetClass,
  937.                      helpForm,
  938.                      XtNfromVert, helpDoneButton,
  939.                      XtNfromHoriz, NULL,
  940.                      XtNtop, XawChainTop,
  941.                      XtNbottom, XawChainBottom,
  942.                      XtNleft, XawChainLeft,
  943.                      XtNright, XawChainRight,
  944.                      XtNeditType, XawtextRead,
  945.                      XtNdisplayCaret, FALSE,
  946.                      XtNscrollVertical, XawtextScrollAlways,
  947.                      XtNscrollHorizontal, 
  948.                      XawtextScrollWhenNeeded,
  949.                      XtNuseStringInPlace, TRUE,
  950.                      XtNstring, help_text,
  951.                      XtNwidth, 530,
  952.                      XtNheight, 650,
  953.                      NULL);
  954. }
  955.  
  956. /* ----------------------------------------------------------------------------
  957.  * 
  958.  *   BuildApplicationWindow() assumes that TreeTopLevel has been initialized 
  959.  *   by XtInitialize(). TreeDrawingArea is set to the drawing area in this
  960.  *   application window.
  961.  * 
  962.  * ----------------------------------------------------------------------------
  963.  */
  964.  
  965.  
  966. static void
  967. BuildApplicationWindow(parent)
  968.      Widget parent;
  969. {
  970.   Widget    topPane, box;
  971.  
  972.   topPane = XtVaCreateManagedWidget("topPane",
  973.                     panedWidgetClass,
  974.                     parent,
  975.                     XtNorientation, XtorientVertical,
  976.                     NULL);
  977.  
  978.   BuildMenubar(topPane);
  979.  
  980.   statusText = XtVaCreateManagedWidget("statusText",
  981.                        labelWidgetClass,
  982.                        topPane,
  983.                        XtNborderWidth, 0,
  984.                        NULL);
  985.  
  986.   scrolledWindow = XtVaCreateManagedWidget("scrolledWindow",
  987.                        viewportWidgetClass,
  988.                        topPane, 
  989.                        XtNshowGrip, FALSE,
  990.                        XtNallowHoriz, TRUE,
  991.                        XtNallowVert, TRUE,
  992.                        XtNuseBottom, TRUE,
  993.                        XtNuseRight, TRUE,
  994.                        NULL);
  995.  
  996.   TreeDrawingArea = XtVaCreateManagedWidget("treeDrawingArea",
  997.                         simpleWidgetClass,
  998.                         scrolledWindow,
  999.                         NULL);
  1000. }
  1001.  
  1002. /* ----------------------------------------------------------------------------
  1003.  * 
  1004.  *   HandleError() is used when ReadTreeFromFile() or SaveTreeToFile() returns
  1005.  *   an error. 
  1006.  * 
  1007.  * ----------------------------------------------------------------------------
  1008.  */
  1009.  
  1010. void
  1011. HandleError(error, tree)
  1012.      ErrCode error;
  1013.      Tree *tree;
  1014. {
  1015.   Widget    dlg, text;
  1016.   
  1017.   if (tree) {
  1018.     dlg = XtNameToWidget(dialog[DLG_INFO], "dlgInfoForm");
  1019.     if (dlg) {
  1020.       XtVaSetValues(dlg, 
  1021.             XtNvalue, errStr[error],
  1022.             XtNwidth, 200,
  1023.             NULL);
  1024.       text = XtNameToWidget(dlg, "value");
  1025.       if (text) {
  1026.     XtVaSetValues(text, XtNdisplayCaret, FALSE, NULL);
  1027.     XtVaSetValues(XawTextGetSource(text), XtNeditType, XawtextRead, NULL);
  1028.       }
  1029.     }
  1030.     popup_dialog(dialog[DLG_INFO], XtGrabExclusive);
  1031.   } else {
  1032.     dlg = XtNameToWidget(dialog[DLG_ERROR], "dlgErrorForm");
  1033.     if (dlg) {
  1034.       XtVaSetValues(dlg, 
  1035.             XtNvalue, errStr[error], 
  1036.             XtNwidth, 200,
  1037.             NULL);
  1038.       text = XtNameToWidget(dlg, "value");
  1039.       if (text) {
  1040.     XtVaSetValues(text, XtNdisplayCaret, FALSE, NULL);
  1041.     XtVaSetValues(XawTextGetSource(text), XtNeditType, XawtextRead, NULL);
  1042.       }
  1043.     }
  1044.     popup_dialog(dialog[DLG_ERROR], XtGrabExclusive);
  1045.   }
  1046. }
  1047.  
  1048.  
  1049. /* ----------------------------------------------------------------------------
  1050.  * 
  1051.  *   InitializeInterface() initializes the environment for displaying
  1052.  *   the tree and creates the necessary supporting structures for interaction
  1053.  *   and display. This function should be called only once.
  1054.  * 
  1055.  * ----------------------------------------------------------------------------
  1056.  */
  1057.  
  1058. void
  1059. InitializeInterface(argc, argv)
  1060.      int *argc;
  1061.      char *argv[];
  1062. {
  1063.   XrmValue       rmvalue;
  1064.   char          *rmtype;
  1065.   Window         win;
  1066.   Pixel          background;
  1067.   XColor         colors[NUM_COLORS];
  1068.   Colormap       cmap;
  1069.   Pixmap         gray_pixmap;
  1070.   Atom         wm_delete_window;
  1071.  
  1072.   /* XtSetLanguageProc is broken on some systems.
  1073.      The symptom is an error of the form:
  1074.         Warning: X locale modifiers not supported, using default
  1075.      so don't use this call:
  1076.  
  1077.         XtSetLanguageProc(NULL, NULL, NULL);
  1078.   */
  1079.   
  1080.   TreeTopLevel = XtVaAppInitialize(&app, "Xoobr", 
  1081.                    NULL, 0,
  1082.                    argc, argv, 
  1083.                    fallback_resources, 
  1084.                    NULL);
  1085.   
  1086.   ASSERT(TreeTopLevel, "failed to open connection to X server");
  1087.   
  1088.   TreeDisplay = XtDisplay(TreeTopLevel);
  1089.   TreeScreen  = DefaultScreen(TreeDisplay);
  1090.  
  1091.   /* set up color resources */
  1092.   applRsrcsPtr = &applRsrcs;
  1093.   XtGetApplicationResources(TreeTopLevel, applRsrcsPtr,
  1094.                 applRsrcsDesc, XtNumber(applRsrcsDesc),
  1095.                 NULL, 0);
  1096.  
  1097.   /* add actions */
  1098.   XtAppAddActions(app, local_actions, 6);
  1099.   XawSimpleMenuAddGlobalActions(app);
  1100.   
  1101.   TreeContourWidth = applRsrcsPtr->contour_width;
  1102.   
  1103.   /* set up label font info */
  1104.   if (XrmGetResource(XtDatabase(TreeDisplay),
  1105.              X11_FONT_RESOURCE, X11_FONT_CLASS_RESOURCE,
  1106.              &rmtype, &rmvalue)) {
  1107.     if (! (TreeLabelFont = XLoadQueryFont(TreeDisplay, rmvalue.addr)) ) {
  1108.       WARN_4("cannot load user-specified font:", rmvalue.addr,
  1109.          "using font:", X11_DEFAULT_FONT);
  1110.       TreeLabelFont = XLoadQueryFont(TreeDisplay, X11_DEFAULT_FONT);
  1111.     }
  1112.   }
  1113.   else
  1114.     TreeLabelFont = XLoadQueryFont(TreeDisplay, X11_DEFAULT_FONT);
  1115.   TreeLabelFont = XLoadQueryFont(TreeDisplay, "fixed");
  1116.   
  1117.   check_pixmap =
  1118.     XCreateBitmapFromData(TreeDisplay, RootWindow(TreeDisplay, TreeScreen),
  1119.               check_bits, check_width, check_height);
  1120.   
  1121.   slider_pixmap =
  1122.     XCreateBitmapFromData(TreeDisplay, RootWindow(TreeDisplay, TreeScreen),
  1123.               slider_pixmap_bits, slider_pixmap_width, 
  1124.               slider_pixmap_height);
  1125.   
  1126.   BuildApplicationWindow(TreeTopLevel);
  1127.   BuildHelpWindow(TreeTopLevel);
  1128.   BuildPopupMenus(TreeTopLevel);
  1129.   BuildDialogs(TreeTopLevel);
  1130.   
  1131.   
  1132.   XtAddEventHandler(TreeDrawingArea, ExposureMask, FALSE,
  1133.             ExposeHandler, (XtPointer) NULL);
  1134.   
  1135.   XtVaSetValues(TreeDrawingArea, 
  1136.         XtNbackground, applRsrcsPtr->background_color, 
  1137.         NULL);
  1138.   
  1139.   XtRealizeWidget(TreeTopLevel);
  1140.   
  1141.   XtOverrideTranslations
  1142.     (TreeTopLevel,
  1143.      XtParseTranslationTable("<Message>WM_PROTOCOLS: quit()"));
  1144.  
  1145.   wm_delete_window = XInternAtom(TreeDisplay, "WM_DELETE_WINDOW", FALSE);
  1146.   (void) XSetWMProtocols(TreeDisplay, XtWindow(TreeTopLevel),
  1147.              &wm_delete_window, 1);
  1148.  
  1149.  
  1150.   win = XtWindow(TreeDrawingArea);
  1151.   cmap = DefaultColormap(TreeDisplay, TreeScreen);
  1152.   
  1153.   /* set up double buffer */
  1154.   colors[BACKGROUND_COLOR].pixel = applRsrcsPtr->background_color;
  1155.   XQueryColor(TreeDisplay, cmap, &(colors[BACKGROUND_COLOR]));
  1156.   colors[TREE_COLOR].pixel = applRsrcsPtr->tree_color;
  1157.   XQueryColor(TreeDisplay, cmap, &(colors[TREE_COLOR]));
  1158.   colors[CONTOUR_COLOR].pixel = applRsrcsPtr->contour_color;
  1159.   XQueryColor(TreeDisplay, cmap, &(colors[CONTOUR_COLOR]));
  1160.   colors[HIGHLIGHT_COLOR].pixel = applRsrcsPtr->highlight_color;
  1161.   XQueryColor(TreeDisplay, cmap, &(colors[HIGHLIGHT_COLOR]));
  1162.   colors[SPLIT_COLOR].pixel = applRsrcsPtr->split_color;
  1163.   XQueryColor(TreeDisplay, cmap, &(colors[SPLIT_COLOR]));
  1164.   colors[ACTION_COLOR].pixel = applRsrcsPtr->action_color;
  1165.   XQueryColor(TreeDisplay, cmap, &(colors[ACTION_COLOR]));
  1166.   
  1167.   TreeDrawingAreaDB = 
  1168.     DBLcreate_double_buffer(TreeDisplay, 
  1169.                 XtWindow(TreeDrawingArea), FALSE,
  1170.                 colors, NUM_COLORS);
  1171.  
  1172.   ASSERT(TreeDrawingAreaDB, "could not create double buffer");
  1173.   
  1174.   background = DBLinq_background(TreeDrawingAreaDB);
  1175.   
  1176.   
  1177.   XtVaSetValues(TreeDrawingArea, XtNbackground, background, NULL);
  1178.   
  1179.   /* also set the scrolledWindow background to same color */
  1180.   XtVaSetValues(XtParent(TreeDrawingArea), XtNbackground, background, NULL);
  1181.   
  1182.   XSetFont(TreeDrawingAreaDB->display, TreeDrawingAreaDB->gc,
  1183.        TreeLabelFont->fid); 
  1184.   
  1185.   gray_pixmap =
  1186.     XCreatePixmapFromBitmapData(TreeDisplay, XtWindow(TreeDrawingArea),
  1187.                 gray_bits, gray_width, gray_height,
  1188.                 TreeDrawingAreaDB->colors[TREE_COLOR],
  1189.                 background,
  1190.                 DefaultDepth(TreeDisplay, TreeScreen));
  1191.   
  1192. #ifdef COMMENT
  1193.   XtVaSetValues(treeMenuItems[LAYOUT_MENU_VARIABLE],
  1194.         XtNleftBitmap, check_pixmap, 
  1195.         NULL);
  1196. #endif
  1197.  
  1198.   XSetTile(TreeDrawingAreaDB->display, TreeDrawingAreaDB->gc, gray_pixmap);
  1199.   SetDrawColor(TREE_COLOR);
  1200.   
  1201.   InitializeDissolveEffect(TreeDisplay, XtWindow(TreeDrawingArea),
  1202.                TreeDrawingAreaDB->colors[TREE_COLOR], background);
  1203.   
  1204.   PauseCursor = XCreateFontCursor(TreeDisplay, XC_watch);
  1205.   
  1206.   StatusMsg("Ready", TRUE);
  1207. }
  1208.  
  1209.  
  1210. /* ----------------------------------------------------------------------------
  1211.  * 
  1212.  *   UserEventLoop() is called after InitializeInterface() to handle
  1213.  *   processing of events.
  1214.  * 
  1215.  * ----------------------------------------------------------------------------
  1216.  */
  1217.  
  1218. void
  1219. UserEventLoop()
  1220. {
  1221.   XtAppMainLoop(app);
  1222. }
  1223.  
  1224.  
  1225. /* ------------------------------------------------------------------------- */
  1226. /*              Callback Routines                                  */
  1227. /* ------------------------------------------------------------------------- */
  1228.  
  1229. static void
  1230. TreeMenu_CB(w, client_data, call_data)
  1231.      Widget w;
  1232.      XtPointer client_data;
  1233.      XtPointer call_data;
  1234. {
  1235.   long        menuItem = (long) client_data;
  1236.   Widget    dlgFileForm;
  1237.   
  1238.   switch (menuItem) {
  1239.   case TREE_MENU_NEW:
  1240.     popup_dialog(dialog[DLG_NEW], XtGrabExclusive);
  1241.     break;
  1242.   case TREE_MENU_LOAD:
  1243.     loading_file = 1;
  1244.     XtVaSetValues(dialog[DLG_FILE],  XtNtitle, "Load File", NULL);
  1245.     dlgFileForm = XtNameToWidget(dialog[DLG_FILE], "dlgFileForm");
  1246.     XtVaSetValues(dlgFileForm, XtNvalue, "", NULL);
  1247.     popup_dialog(dialog[DLG_FILE], XtGrabExclusive);
  1248.     break;
  1249.   case TREE_MENU_SAVE:
  1250.     loading_file = 0;
  1251.     XtVaSetValues(dialog[DLG_FILE],  XtNtitle, "Save File", NULL);
  1252.     dlgFileForm = XtNameToWidget(dialog[DLG_FILE], "dlgFileForm");
  1253.     XtVaSetValues(dlgFileForm, XtNvalue, "", NULL);
  1254.     popup_dialog(dialog[DLG_FILE], XtGrabExclusive);
  1255.     break;
  1256.   case TREE_MENU_QUIT:
  1257.     exit(0);
  1258.     break;
  1259.     
  1260.   default:
  1261.     WARN("unknown menu item in TreeMenu_CB");
  1262.   }
  1263. }
  1264.  
  1265.  
  1266. /* ------------------------------------------------------------------------- */
  1267.  
  1268. static void
  1269. LayoutMenu_CB(w, client_data, call_data)
  1270.      Widget w;
  1271.      XtPointer client_data;
  1272.      XtPointer call_data;
  1273. {
  1274.   long    menuItem = (long) client_data;
  1275.   char    tmpstr[10];
  1276.   
  1277.   switch (menuItem) {
  1278. #ifdef COMMENT
  1279.   case LAYOUT_MENU_FIXED:
  1280.     XtVaSetValues(layoutMenuItems[LAYOUT_MENU_VARIABLE],
  1281.                   XtNleftBitmap, None, NULL);
  1282.     XtVaSetValues(layoutMenuItems[LAYOUT_MENU_FIXED], 
  1283.                   XtNleftBitmap, check_pixmap, NULL);
  1284.  
  1285.     if (TreeLayoutDensity != Fixed) {
  1286.       TreeLayoutDensity = Fixed;
  1287.       DeleteTree(TheTree, TRUE);
  1288.       SetupTree(TheTree);
  1289.     }
  1290.     break;    
  1291.   case LAYOUT_MENU_VARIABLE:
  1292.     XtVaSetValues(layoutMenuItems[LAYOUT_MENU_VARIABLE],
  1293.                   XtNleftBitmap, check_pixmap, NULL);
  1294.     XtVaSetValues(layoutMenuItems[LAYOUT_MENU_FIXED], 
  1295.                   XtNleftBitmap, None, NULL);
  1296.     
  1297.     if (TreeLayoutDensity != Variable) {
  1298.       TreeLayoutDensity = Variable;
  1299.       DeleteTree(TheTree, TRUE);
  1300.       SetupTree(TheTree);
  1301.     }
  1302.     break;
  1303. #endif COMMENT
  1304.   case LAYOUT_MENU_SPACING:
  1305.     dlgLevelValue = TreeParentDistance;
  1306.     dlgSiblingValue = TreeBorderSize;
  1307.     sprintf(tmpstr, "%d  ", dlgLevelValue);
  1308.     XtVaSetValues(dlgLevelValuator, XtNlabel, tmpstr, NULL);
  1309.  
  1310.     /* These setvalues need some adjustments... */
  1311.     XtVaSetValues(dlgLevelScale, 
  1312.           XtNsliderX, (dlgLevelValue * 2),
  1313.           NULL);
  1314.     sprintf(tmpstr, "%d  ", dlgSiblingValue);
  1315.     XtVaSetValues(dlgSiblingValuator, XtNlabel, tmpstr, NULL);
  1316.     XtVaSetValues(dlgSiblingScale, 
  1317.           XtNsliderX, (dlgSiblingValue * 4),
  1318.           NULL);
  1319.     popup_dialog(dialog[DLG_SPACING], XtGrabNone);
  1320.     break;
  1321.   case LAYOUT_MENU_ALIGN_NODES:
  1322.     TreeAlignNodes = !TreeAlignNodes;
  1323.     XtVaSetValues(treeMenuItems[LAYOUT_MENU_ALIGN_NODES],
  1324.           XtNleftBitmap, TreeAlignNodes ? check_pixmap : None, 
  1325.           NULL);
  1326.     DeleteTree(TheTree, TRUE);
  1327.     ResetLabels(TheTree);
  1328.     SetupTree(TheTree);
  1329.     break;
  1330.   default:
  1331.     WARN("unknown menu item in LayoutMenu_CB");
  1332.   }
  1333. }
  1334.  
  1335.  
  1336. /* ------------------------------------------------------------------------- */
  1337.  
  1338. static void
  1339. NodeMenu_CB(w, client_data, call_data)
  1340.      Widget w;
  1341.      XtPointer client_data;
  1342.      XtPointer call_data;
  1343. {
  1344.   long    menuItem = (long) client_data;
  1345.    
  1346.   switch (menuItem) {
  1347.   case NODE_MENU_ADD_CHILD:
  1348.     NodePos = Child;
  1349.     popup_dialog(dialog[DLG_NODE_NAME], XtGrabExclusive);
  1350.     break;
  1351.   case NODE_MENU_ADD_BEFORE:
  1352.     NodePos = Before;
  1353.     popup_dialog(dialog[DLG_NODE_NAME], XtGrabExclusive);
  1354.     break;
  1355.   case NODE_MENU_ADD_AFTER:
  1356.     NodePos = After;
  1357.     popup_dialog(dialog[DLG_NODE_NAME], XtGrabExclusive);
  1358.     break;
  1359.   case NODE_MENU_ELISION:
  1360.     ExpandCollapseNode(PopupNode);
  1361.     break;
  1362.   case NODE_MENU_DELETE:
  1363.     DeleteNode(PopupNode);
  1364.     if (TheTree == NULL)
  1365.       XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], FALSE);
  1366.     break;
  1367.   default:
  1368.     WARN("unknown menu item in NodeMenu_CB");
  1369.   }
  1370. }
  1371.  
  1372.  
  1373. /* ------------------------------------------------------------------------- */
  1374.  
  1375. static void
  1376. Help_CB(w, client_data, call_data)
  1377.      Widget w;
  1378.      XtPointer client_data;
  1379.      XtPointer call_data;
  1380. {
  1381.   popup_dialog(helpShell, XtGrabNone);
  1382. }
  1383.  
  1384.  
  1385. /* ------------------------------------------------------------------------- */
  1386.  
  1387. static void
  1388. HelpDone_CB(w, client_data, call_data)
  1389.      Widget w;
  1390.      XtPointer client_data;
  1391.      XtPointer call_data;
  1392. {
  1393.   XtPopdown(helpShell);
  1394. }
  1395.  
  1396.  
  1397. /* ------------------------------------------------------------------------- */
  1398.  
  1399. static void
  1400. NodeLabel_CB(w, client_data, call_data)
  1401.      Widget w;
  1402.      XtPointer client_data;
  1403.      XtPointer call_data;
  1404. {
  1405.   char    *node_label;
  1406.  
  1407.   XtPopdown(dialog[DLG_NODE_NAME]);
  1408.   if (client_data == (XtPointer) TRUE) {
  1409.     node_label = XtMalloc(strlen(XawDialogGetValueString(XtParent(w)))
  1410.               * sizeof(char));
  1411.     node_label = strcpy(node_label, XawDialogGetValueString(XtParent(w)));
  1412.     if (*node_label) 
  1413.       InsertNode(PopupNode, NodePos, node_label);
  1414.   }
  1415. }
  1416.       
  1417.  
  1418. /* ------------------------------------------------------------------------- */
  1419.  
  1420. static void
  1421. NewTree_CB(w, client_data, call_data)
  1422.      Widget w;
  1423.      XtPointer client_data;
  1424.      XtPointer call_data;
  1425. {
  1426.   char    *node_label;
  1427.   Tree    *tree;
  1428.   
  1429.   XtPopdown(dialog[DLG_NEW]);
  1430.   if (client_data == (XtPointer) TRUE) {
  1431.     node_label = XtMalloc((strlen(XawDialogGetValueString(XtParent(w))) + 1)
  1432.               * sizeof(char));
  1433.     node_label = strcpy(node_label, XawDialogGetValueString(XtParent(w)));
  1434.     if (*node_label) {
  1435.       if (TheTree) {
  1436.     Delete(TheTree);
  1437.     XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], FALSE);
  1438.       }
  1439.       tree = MakeNode();
  1440.       SetNodeLabel(tree, node_label);
  1441.       SetupTree(tree);
  1442.       XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], TRUE);
  1443.     }
  1444.   }
  1445.   XSync(TreeDisplay, FALSE);
  1446. }
  1447.  
  1448.  
  1449. /* ------------------------------------------------------------------------- */
  1450.  
  1451. static void
  1452. File_CB(w, client_data, call_data)
  1453.      Widget w;
  1454.      XtPointer client_data;
  1455.      XtPointer call_data;
  1456. {
  1457.   char *fname;
  1458.   Tree *tree;
  1459.   ErrCode error;
  1460.   Arg args[1];
  1461.   int menuItem;
  1462.   
  1463.   if (client_data == (XtPointer) TRUE) {
  1464.     fname = XawDialogGetValueString(XtParent(w));
  1465.     if (*fname) { 
  1466.       
  1467.       if (loading_file == 1) {
  1468.     if (TheTree) {
  1469.       Delete(TheTree);
  1470.       XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], FALSE);
  1471.     }
  1472.     tree = ReadTreeFromFile(fname, &error);
  1473.     XtPopdown(dialog[DLG_FILE]);
  1474.     if (error != ERR_NONE)
  1475.       HandleError(error, tree);
  1476.     XSync(TreeDisplay, 0);
  1477.     if (tree) {
  1478.       SetupTree(tree);
  1479.       XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], TRUE);
  1480.     } else {
  1481.       SetDrawingTree(NULL);
  1482.       BeginFrame();
  1483.       EndFrame();
  1484.     }
  1485.       } else if (menuItem == TREE_MENU_SAVE) {
  1486.     if (!SaveTreeToFile(TheTree, fname)) {
  1487.       XtPopdown(dialog[DLG_FILE]);
  1488.       HandleError(ERR_OPENFAIL, NULL);
  1489.     } else
  1490.       XtPopdown(dialog[DLG_FILE]);
  1491.       }
  1492.     } else
  1493.       XtPopdown(dialog[DLG_FILE]);
  1494.   } else 
  1495.     XtPopdown(dialog[DLG_FILE]); 
  1496. }
  1497.  
  1498.  
  1499. /* ------------------------------------------------------------------------- */
  1500.  
  1501. static void
  1502. Scale_CB(w, client_data, call_data)
  1503.      Widget w;
  1504.      XtPointer client_data;
  1505.      XtPointer call_data;
  1506. {
  1507.   int    level_value, sibling_value;
  1508.   float    tmp;
  1509.     
  1510.   XtPopdown(dialog[DLG_SPACING]);
  1511.  
  1512.   /* check if OK button was selected */
  1513.   if (client_data) {
  1514.     level_value = dlgLevelValue;
  1515.     
  1516.     sibling_value = dlgSiblingValue;
  1517.     
  1518.     if (level_value != TreeParentDistance ||
  1519.     sibling_value != TreeBorderSize) {
  1520.       
  1521.       TreeParentDistance = level_value;
  1522.       TreeBorderSize = sibling_value;
  1523.       XSync(TreeDisplay, 0);
  1524.       if (TheTree) {
  1525.     DeleteTree(TheTree, TRUE);
  1526.     if (TreeAlignNodes)
  1527.       ResetLabels(TheTree);
  1528.     SetupTree(TheTree);
  1529.       }
  1530.     }
  1531.   }
  1532. }
  1533.  
  1534.  
  1535. /* ------------------------------------------------------------------------- */
  1536. /*                                         */
  1537. /* Auxilary actions and callback functions                                   */
  1538. /*                                         */
  1539. /* ------------------------------------------------------------------------- */
  1540.  
  1541. static void
  1542. Popdown_CB(w, client_data, call_data)
  1543.      Widget w;
  1544.      XtPointer client_data;
  1545.      XtPointer call_data;
  1546. {
  1547.   Widget    widget = (Widget) client_data;
  1548.     
  1549.   XtPopdown(widget);
  1550. }
  1551.  
  1552. static void
  1553. activate_action(w, event, params, num_params)
  1554.      Widget w;
  1555.      XButtonEvent *event;
  1556.      String *params;
  1557.      Cardinal *num_params;
  1558. {
  1559.   Widget    button;
  1560.   
  1561.   if (*num_params == 1) {
  1562.     button = XtNameToWidget(XtParent(w), params[0]);
  1563.     
  1564.     if (button)
  1565.       XtCallCallbacks(button, XtNcallback, (XtPointer) TRUE);
  1566.   }
  1567. }
  1568.  
  1569. static void
  1570. quit_action(w, event, params, num_params)
  1571.      Widget w;
  1572.      XButtonEvent *event;
  1573.      String *params;
  1574.      Cardinal *num_params;
  1575. {
  1576.   exit(0);
  1577. }
  1578.  
  1579.  
  1580.  
  1581. /* ------------------------------------------------------------------------- */
  1582.  
  1583. static void 
  1584. select_action(w, event, params, num_params)
  1585.      Widget w;
  1586.      XButtonEvent *event;
  1587.      String *params;
  1588.      Cardinal *num_params;
  1589. {
  1590.   Tree        *node;
  1591.   int        height;
  1592.   Boolean    edit = FALSE;
  1593.  
  1594.   if ((*num_params > 0) && 
  1595.       (!strcmp(params[0], "EDIT") ||
  1596.        !strcmp(params[0], "edit")))
  1597.     edit = TRUE;
  1598.  
  1599.   if (SearchTree(TheTree, event->x, event->y, &node)) {
  1600.     static Tree *PrevNode = NULL;
  1601.     Tree *ParNode = NULL;
  1602.     
  1603.     PopupNode = node;
  1604.     if (PrevNode != NULL)
  1605.       DrawNode(PrevNode, New);
  1606.     PrevNode = PopupNode;
  1607.     
  1608.     printf("%s^^%s^^%s\n", 
  1609.        EnvNm,
  1610.        edit ? "br-edit" : "br-view",
  1611.        (PopupNode->value) ? PopupNode->value : PopupNode->label.text);
  1612.  
  1613.     StatusMsg(PopupNode->label.text, 1);
  1614.     
  1615.     ParNode = PopupNode->parent;
  1616.     PopupNode->parent = NULL;
  1617.     HiliteNode(PopupNode, New);
  1618.     PopupNode->parent = ParNode;
  1619.   }
  1620. }
  1621.  
  1622. static void 
  1623. menu_popup_action(w, event, params, num_params)
  1624.      Widget w;
  1625.      XEvent *event;
  1626.      String *params;
  1627.      Cardinal *num_params;
  1628. {
  1629.   Widget menu;
  1630.   Boolean popup;
  1631.   ShellWidget shell_widget;
  1632.  
  1633.   char        *strargs[] = {"nodeMenu", NULL};
  1634.   
  1635.   menu = XtNameToWidget(TreeTopLevel, params[0]);
  1636.   shell_widget = (ShellWidget) menu;
  1637.   
  1638.   if (nodeFound) {
  1639.  
  1640.     /* This is giving me a headache. 
  1641.      * Why does popup menus come up unselectable? 
  1642.      */
  1643.  
  1644.     XtCallActionProc(TreeDrawingArea,
  1645.              "XtMenuPopup",
  1646.              event,
  1647.              strargs,
  1648.              1);
  1649.          
  1650. /*
  1651.     XtSetSensitive(menu, TRUE);
  1652.     XtPopupSpringLoaded(menu);
  1653.  */
  1654.  
  1655. /*    if (!XtIsShell(menu)) {
  1656.       printf("error: not shell widget!\n");
  1657.     } else {
  1658.       if (! shell_widget->shell.popped_up) {
  1659.     
  1660.     XtGrabKind call_data = XtGrabExclusive;
  1661.     
  1662.     XtCallCallbacks(menu, XtNpopupCallback, (XtPointer) &call_data);
  1663.     
  1664.     shell_widget->shell.popped_up = TRUE;
  1665.     shell_widget->shell.grab_kind = XtGrabExclusive;
  1666.     shell_widget->shell.spring_loaded = TRUE;
  1667.     
  1668.     if (shell_widget->shell.create_popup_child_proc != NULL) {
  1669.       (*(shell_widget->shell.create_popup_child_proc))(menu);
  1670.     }
  1671.     
  1672.     XtAddGrab(menu, TRUE, TRUE);
  1673.     
  1674.     XtRealizeWidget(menu);
  1675.     
  1676.     XMapRaised(XtDisplay(menu), XtWindow(menu));
  1677.     
  1678.       } else
  1679.     XRaiseWindow(XtDisplay(menu), XtWindow(menu));   
  1680.     }
  1681.     */
  1682.   }
  1683. }
  1684.  
  1685.  
  1686. static void 
  1687. button_action(w, event, params, num_params)
  1688.      Widget w;
  1689.      XEvent *event;
  1690.      String *params;
  1691.      Cardinal *num_params;
  1692. {
  1693.   Tree     *node;
  1694.   
  1695.   if (SearchTree(TheTree, event->xbutton.x, event->xbutton.y, &node)) {
  1696.     
  1697.     nodeFound = TRUE;
  1698.     
  1699.     XtSetSensitive(nodeMenuItems[NODE_MENU_DELETE], TRUE);
  1700.  
  1701.     XtVaSetValues(treeMenus[NODE_MENU], 
  1702.           XtNlabel, node->label.text, 
  1703.           NULL);
  1704.     PopupNode = node;
  1705.     if (IS_LEAF(node))  {
  1706.       
  1707.       XtSetSensitive(nodeMenuItems[NODE_MENU_ELISION], FALSE);
  1708.       
  1709.       XtVaSetValues(nodeMenuItems[NODE_MENU_ELISION], 
  1710.             XtNlabel, labelStr[STR_NODE_COLLAPSE], 
  1711.             NULL);
  1712.       
  1713.     } else {
  1714.       
  1715.       XtSetSensitive(nodeMenuItems[NODE_MENU_ELISION], TRUE);
  1716.       if (node->elision) {
  1717.     XtVaSetValues(nodeMenuItems[NODE_MENU_ELISION],
  1718.               XtNlabel, labelStr[STR_NODE_EXPAND],
  1719.               NULL);
  1720.       } else {
  1721.     XtVaSetValues(nodeMenuItems[NODE_MENU_ELISION],
  1722.               XtNlabel, labelStr[STR_NODE_COLLAPSE],
  1723.               NULL);
  1724.       }
  1725.     }
  1726.     
  1727.     if (node->parent) {
  1728.       XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_BEFORE], TRUE);
  1729.       XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_AFTER], TRUE);
  1730.     } else {
  1731.       XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_BEFORE], FALSE);
  1732.       XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_AFTER], FALSE);
  1733.     }
  1734.     
  1735.     if (node->elision) {
  1736.       XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_CHILD], FALSE);
  1737.     } else {
  1738.       XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_CHILD], TRUE);
  1739.     }
  1740.     
  1741.   } else {
  1742.     nodeFound = FALSE;
  1743.  
  1744.     XtVaSetValues(treeMenus[NODE_MENU], 
  1745.           XtNlabel, " ", 
  1746.           NULL);
  1747.  
  1748.     XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_BEFORE], FALSE);
  1749.     XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_AFTER], FALSE);
  1750.     XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_CHILD], FALSE);
  1751.     XtSetSensitive(nodeMenuItems[NODE_MENU_ELISION], FALSE);
  1752.     XtSetSensitive(nodeMenuItems[NODE_MENU_DELETE], FALSE);
  1753.   }
  1754. }
  1755.  
  1756.  
  1757. /* ------------------------------------------------------------------------- */
  1758. /*                                         */
  1759. /* General purpose popdown widget callback (for dialog popdown buttons)      */
  1760. /*                                         */
  1761. /* ------------------------------------------------------------------------- */
  1762.  
  1763. static void center_widget(w, x, y)
  1764. Widget w;
  1765. int x, y;
  1766. {
  1767.   Dimension    width, height, border;
  1768.   Position    max_x, max_y;
  1769.   
  1770.   XtVaGetValues(w,
  1771.         XtNwidth, &width,
  1772.         XtNheight, &height,
  1773.         XtNborderWidth, &border,
  1774.         NULL);
  1775.   
  1776.   width += 2 * border;
  1777.   height += 2 * border;
  1778.   
  1779.   x -= ((Position) width / 2);
  1780.   y -= ((Position) height / 2);
  1781.   
  1782.   if (x < 0) x = 0;
  1783.   if (y < 0) y = 0;
  1784.   
  1785.   if (x > (max_x = (Position) (XtScreen(w)->width - width)) )
  1786.     x = max_x;
  1787.   
  1788.   if (y > (max_y = (Position) (XtScreen(w)->height - height)) )
  1789.     y = max_y;
  1790.   
  1791.   XtVaSetValues(w,
  1792.         XtNx, x,
  1793.         XtNy, y,
  1794.         NULL);
  1795. }
  1796.  
  1797. #define shell_translations "<Message>WM_PROTOCOLS: wmpopdown()\n"
  1798.              
  1799. static void 
  1800. popup_dialog(shell, grab_kind)
  1801.      Widget shell;
  1802.      XtGrabKind grab_kind;
  1803. {
  1804.   int        idummy, x, y;
  1805.   Window    wdummy;
  1806.  
  1807.   XtOverrideTranslations(shell, XtParseTranslationTable(shell_translations));
  1808.   XtRealizeWidget(shell);
  1809.   wm_delete_window = XInternAtom(XtDisplay(shell), "WM_DELETE_WINDOW", 
  1810.                  FALSE);
  1811.   (void) XSetWMProtocols(XtDisplay(shell), XtWindow(shell),
  1812.              &wm_delete_window, 1);
  1813.   
  1814.   XQueryPointer(TreeDisplay, DefaultRootWindow(TreeDisplay), 
  1815.         &wdummy, &wdummy,
  1816.         &x, &y, &idummy, &idummy, &idummy);
  1817.   
  1818.   center_widget(shell, x, y);
  1819.   
  1820.   XtPopup(shell, grab_kind);
  1821. }
  1822.  
  1823. static void 
  1824. popdown_action(widget, event, params, num_params)
  1825.      Widget widget;
  1826.      XEvent *event;
  1827.      String *params;
  1828.      Cardinal *num_params;
  1829. {
  1830.   XtPopdown(widget);
  1831. }
  1832.  
  1833. static void 
  1834. set_siblingscale_CB(widget, w, percent_ptr)
  1835.      Widget widget;
  1836.      XtPointer w;
  1837.      XtPointer percent_ptr;
  1838. {
  1839.   char tmpstr[10];
  1840.   
  1841.   sprintf(tmpstr, "%d  ", (int) (*(float*) percent_ptr*MAX_BORDER_SIZE));
  1842.   
  1843.   XtVaSetValues((Widget) w, XtNlabel, tmpstr, NULL);
  1844. }
  1845.  
  1846. static void 
  1847. siblingscale_CB(widget, w, report)
  1848.      Widget widget;
  1849.      XtPointer w;
  1850.      XawPannerReport *report;
  1851. {
  1852.   char tmpstr[10];
  1853.   
  1854.   sprintf(tmpstr, "%d ", (int) 
  1855.       ((float) report->slider_x / report->slider_width 
  1856.        * MAX_BORDER_SIZE / 10));
  1857.   
  1858.   XtVaSetValues((Widget) w, XtNlabel, tmpstr, NULL);
  1859. }
  1860.  
  1861. static void
  1862. set_levelscale_CB(widget, w, percent_ptr)
  1863.      Widget widget;
  1864.      XtPointer w;
  1865.      XtPointer percent_ptr;
  1866. {
  1867.   char    tmpstr[10];
  1868.  
  1869.   sprintf(tmpstr, "%d  ", (int) (*(float*) percent_ptr*MAX_PARENT_DISTANCE));
  1870.  
  1871.   XtVaSetValues((Widget) w, XtNlabel, tmpstr, NULL);
  1872. }
  1873.  
  1874. static void
  1875. levelscale_CB(widget, w, report)
  1876.      Widget widget;
  1877.      XtPointer w;
  1878.      XawPannerReport *report;
  1879. {
  1880.   char    tmpstr[10];
  1881.   
  1882.   sprintf(tmpstr, "%d ", (int) 
  1883.       ((float) report->slider_x / report->slider_width 
  1884.        * MAX_PARENT_DISTANCE / 10));
  1885.   
  1886.   XtVaSetValues((Widget) w, XtNlabel, tmpstr, NULL);
  1887. }
  1888.  
  1889. static void 
  1890. set_siblingvalue_CB(widget, var_ptr, percent_ptr)
  1891.      Widget widget;
  1892.      XtPointer var_ptr;
  1893.      XtPointer percent_ptr;
  1894. {
  1895.   * (int *)var_ptr = (int) (*(float*) percent_ptr*MAX_BORDER_SIZE);
  1896. }
  1897.  
  1898. static void 
  1899. set_levelvalue_CB(widget, var_ptr, percent_ptr)
  1900.      Widget widget;
  1901.      XtPointer var_ptr;
  1902.      XtPointer percent_ptr;
  1903. {
  1904.   * (int *)var_ptr = (int) (*(float*) percent_ptr*MAX_PARENT_DISTANCE);
  1905. }
  1906.  
  1907.  
  1908. static void 
  1909. siblingvalue_CB(widget, var_ptr, report)
  1910.      Widget widget;
  1911.      XtPointer var_ptr;
  1912.      XawPannerReport *report;
  1913. {
  1914.   * (int *) var_ptr = (int) 
  1915.     ((float) report->slider_x / report->slider_width 
  1916.      * MAX_BORDER_SIZE / 10);
  1917. }
  1918.  
  1919. static void 
  1920. levelvalue_CB(widget, var_ptr, report)
  1921.      Widget widget;
  1922.      XtPointer var_ptr;
  1923.      XawPannerReport *report;
  1924. {
  1925.   * (int *) var_ptr = (int) 
  1926.     ((float) report->slider_x / report->slider_width 
  1927.      * MAX_PARENT_DISTANCE / 10);
  1928. }
  1929.  
  1930.  
  1931. /* ----------------------------------------------------------------------------
  1932.  * 
  1933.  *   Main routine
  1934.  * 
  1935.  * ----------------------------------------------------------------------------
  1936.  */
  1937.  
  1938. main(argc, argv)
  1939.      int argc;
  1940.      char *argv[];
  1941. {
  1942.   Tree *tree = NULL;
  1943.   ErrCode error = ERR_NONE;
  1944.   
  1945.   ProgramName = strdup(argv[0]);
  1946.   if (ProgramName == NULL) {
  1947.     fprintf(stderr, "%s: insufficient memory available\n", argv[0]);
  1948.     exit(0);
  1949.   }
  1950.   
  1951.   InitializeInterface(&argc, argv);
  1952.   XSync(TreeDisplay, 0);
  1953.  
  1954.   if (argc >= 2) {
  1955.     tree = ReadTreeFromFile(argv[1], &error);
  1956.     if (tree) StatusMsg(argv[1], TRUE);
  1957.     if (argc > 2)
  1958.       WARN("extraneous arguments ignored");
  1959.   } 
  1960.      
  1961.   if (tree) {
  1962.     SetupTree(tree);
  1963.     XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], TRUE);
  1964.   } else {
  1965.     SetDrawingTree(NULL);
  1966.     XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], FALSE);
  1967.   }
  1968.  
  1969.   if (error != ERR_NONE)
  1970.     HandleError(error, tree);
  1971.   
  1972.   StatusMsg("Left = Edit Node; Mid = View Node; Right = Node Menu", 1);
  1973.   UserEventLoop();
  1974. }
  1975.  
  1976. /* ------------------------------------------------------------------------- */
  1977. /*                  End of File                                */
  1978. /* ------------------------------------------------------------------------- */
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.